package com.woohua.demo.config.web;

import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.LogoutConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

import javax.annotation.Resource;
import javax.sql.DataSource;


/**
 * @version 1.0
 * @author: woo hua
 * @DATE 2022/9/1 13:29
 * @description: SpringSecurity 5.4 以上新用法配置
 * 为避免循环依赖，仅用于配置 HttpSecurity
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    @Resource
    private DataSourceProperties dataSourceProperties;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .authorizeHttpRequests((requests) -> requests
                        .antMatchers("/", "/home", "/kaptcha").permitAll()
                        .antMatchers("/user/**").permitAll()
                        .anyRequest().authenticated()
                )
                .formLogin((form) -> form.loginPage("/login").permitAll()
                )
                .csrf().disable()  // 关闭跨域请求伪造，用于测试环境。正式环境需要自己实现
                .logout(LogoutConfigurer::permitAll);
        return httpSecurity.build();
    }

    @Bean
    public DataSource dataSource() {
        return new DriverManagerDataSource(dataSourceProperties.getUrl()
                , dataSourceProperties.getUsername()
                , dataSourceProperties.getPassword()
        );
    }

    /**
     * 密码不需要加密
     * @return 加密方式
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }

    @Bean
    public UserDetailsService userDetailsService(DataSource dataSource) {
        return new JdbcUserDetailsManager(dataSource);
    }

}
